package com.wcbtest.dem02.service;

import com.wcbtest.dem02.entity.CpuInfo;
import com.wcbtest.dem02.entity.MemoryInfo;
import com.wcbtest.dem02.entity.ProcessInfo;
import com.wcbtest.dem02.entity.SystemInfo;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class TopOutputParser {

    // 更灵活的CPU信息匹配模式
    private static final Pattern CPU_PATTERN = Pattern.compile(
        "Cpu\\(s\\):\\s*(\\d+\\.\\d+)%?\\s*us(?:,|\\s)+(\\d+\\.\\d+)%?\\s*sy(?:,|\\s)+" +
        "(\\d+\\.\\d+)%?\\s*ni(?:,|\\s)+(\\d+\\.\\d+)%?\\s*id(?:,|\\s)+" +
        "(\\d+\\.\\d+)%?\\s*wa(?:,|\\s)*(?:(\\d+\\.\\d+)%?\\s*hi(?:,|\\s)*)?" +
        "(?:(\\d+\\.\\d+)%?\\s*si(?:,|\\s)*)?(?:(\\d+\\.\\d+)%?\\s*st)?",
        Pattern.CASE_INSENSITIVE
    );

    // 更灵活的内存信息匹配模式
    private static final Pattern MEM_PATTERN = Pattern.compile(
        "Mem:\\s*(\\d+)\\s*(\\w*)\\s*total,\\s*(\\d+)\\s*(\\w*)\\s*used,\\s*" +
        "(\\d+)\\s*(\\w*)\\s*free(?:,\\s*(\\d+)\\s*(\\w*)\\s*buffers)?",
        Pattern.CASE_INSENSITIVE
    );

    // 更灵活的交换空间匹配模式
    private static final Pattern SWAP_PATTERN = Pattern.compile(
        "Swap:\\s*(\\d+)\\s*(\\w*)\\s*total,\\s*(\\d+)\\s*(\\w*)\\s*used,\\s*" +
        "(\\d+)\\s*(\\w*)\\s*free(?:,\\s*(\\d+)\\s*(\\w*)\\s*cached)?",
        Pattern.CASE_INSENSITIVE
    );

    // 进程信息头部检测
    private static final Pattern PROCESS_HEADER_PATTERN = Pattern.compile(
        "^\\s*PID\\s+USER\\s+PR\\s+NI\\s+VIRT\\s+RES\\s+SHR\\s+S\\s+%CPU\\s+%MEM\\s+TIME\\+\\s+COMMAND.*$",
        Pattern.CASE_INSENSITIVE
    );


    //public static final Pattern CPU_PATTERN = Pattern.compile("Cpu\\(s\\):\\s+(\\d+\\.\\d+)%us,\\s+(\\d+\\.\\d+)%sy,\\s+(\\d+\\.\\d+)%ni,\\s+(\\d+\\.\\d+)%id,\\s+(\\d+\\.\\d+)%wa,\\s+(\\d+\\.\\d+)%hi,\\s+(\\d+\\.\\d+)%si,\\s+(\\d+\\.\\d+)%st");
    public static final Pattern CPU_CORES_PATTERN = Pattern.compile("CPU\\(s\\):\\s+(\\d+)");
    //public static final Pattern MEM_PATTERN = Pattern.compile("Mem:\\s+(\\d+) total,\\s+(\\d+) used,\\s+(\\d+) free,\\s+(\\d+) buffers\\/cache");

    public SystemInfo parseTopOutput(String topOutput) {
        SystemInfo systemInfo = new SystemInfo();
        systemInfo.setCpuInfo(parseCpuInfo(topOutput));
        systemInfo.setMemoryInfo(parseMemoryInfo(topOutput));
        systemInfo.setProcessList(parseProcesses(topOutput));
        return systemInfo;
    }

    private CpuInfo parseCpuInfo(String topOutput) {
        CpuInfo cpuInfo = new CpuInfo();
        List<String> lines = Arrays.asList(topOutput.split("\n"));
        for (String line : lines) {
            Matcher cpuMatcher = CPU_PATTERN.matcher(line);

            if (cpuMatcher.find()) {
                cpuInfo.setUser(Double.parseDouble(cpuMatcher.group(1)));
                cpuInfo.setSystem(Double.parseDouble(cpuMatcher.group(2)));
                cpuInfo.setIdle(Double.parseDouble(cpuMatcher.group(4)));
                cpuInfo.setIowait(Double.parseDouble(cpuMatcher.group(5)));
                cpuInfo.setIrq(Double.parseDouble(cpuMatcher.group(6)));
                cpuInfo.setSoftirq(Double.parseDouble(cpuMatcher.group(7)));
                cpuInfo.setSteal(Double.parseDouble(cpuMatcher.group(8)));
            }
            // 解析CPU核心数
            Matcher cpuCoresMatcher = CPU_CORES_PATTERN.matcher(line);
            if (cpuCoresMatcher.find()) {
                cpuInfo.setCpuCores(Integer.parseInt(cpuCoresMatcher.group(1)));
            }

        }

        return cpuInfo;
    }

    private MemoryInfo parseMemoryInfo(String topOutput) {
        MemoryInfo memoryInfo = new MemoryInfo();
        Matcher memMatcher = MEM_PATTERN.matcher(topOutput);

        if (memMatcher.find()) {
            long totalMemory = Long.parseLong(memMatcher.group(1));
            long usedMemory = Long.parseLong(memMatcher.group(2));
            long freeMemory = Long.parseLong(memMatcher.group(3));
            long bufferCache = Long.parseLong(memMatcher.group(4));
            
            // 将KB转换为MB
            memoryInfo.setTotalMemory(totalMemory / 1024);
            memoryInfo.setUsedMemory(usedMemory / 1024);
            memoryInfo.setFreeMemory(freeMemory / 1024);
            memoryInfo.setBufferCache(bufferCache / 1024);
            memoryInfo.setAvailableMemory((freeMemory + bufferCache) / 1024);
        }

        Pattern swapPattern = Pattern.compile("Swap:\\s+(\\d+) total,\\s+(\\d+) used,\\s+(\\d+) free");
        Matcher swapMatcher = swapPattern.matcher(topOutput);

        if (swapMatcher.find()) {
            long totalSwap = Long.parseLong(swapMatcher.group(1));
            long usedSwap = Long.parseLong(swapMatcher.group(2));
            long freeSwap = Long.parseLong(swapMatcher.group(3));
            
            // 将KB转换为MB
            memoryInfo.setTotalSwap(totalSwap / 1024);
            memoryInfo.setUsedSwap(usedSwap / 1024);
            memoryInfo.setFreeSwap(freeSwap / 1024);
        }

        return memoryInfo;
    }

    private List<ProcessInfo> parseProcesses(String topOutput) {
        List<ProcessInfo> processes = new ArrayList<>();
        String[] lines = topOutput.split("\n");
        
        boolean startParsing = false;
        for (String line : lines) {
            if (line.trim().startsWith("PID")) {
                startParsing = true;
                continue;
            }
            
            if (startParsing && !line.trim().isEmpty()) {
                ProcessInfo process = parseProcessLine(line);
                if (process != null) {
                    processes.add(process);
                }
            }
        }
        
        return processes;
    }

    private ProcessInfo parseProcessLine(String line) {
        try {
            String[] parts = line.trim().split("\\s+", 12);
            if (parts.length >= 12) {
                ProcessInfo process = new ProcessInfo();
                process.setPid(Integer.parseInt(parts[0]));
                process.setUser(parts[1]);
                process.setCpu(Double.parseDouble(parts[8]));
                process.setMem(Double.parseDouble(parts[9]));
                process.setVsz(Long.parseLong(parts[4]));
                process.setRss(Long.parseLong(parts[5]));
                process.setStatus(parts[7]);
                process.setTime(parts[10]);
                process.setCommand(parts[11]);
                return process;
            }
        } catch (Exception e) {
            // 忽略解析错误的行
        }
        return null;
    }
}    